﻿//========================================================= 
/**@file LC_EncryptProvider.h
 * @brief 适配ISecurityAlgorithm提供给LC_EncryptCmdAdapter使用
 * 
 * @date 2017-10-14   10:52:29
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_LC_ENCRYPTPROVIDER_H_
#define _LIBZHOUYB_LC_ENCRYPTPROVIDER_H_
//--------------------------------------------------------- 
#include "../../../extension/security/security.h"
using zhou_yb::extension::security::ISecurityAlgorithm;
//--------------------------------------------------------- 
namespace zhou_yb {
namespace application {
namespace lc {
//--------------------------------------------------------- 
/**
 * @brief 用于16进制数据流处理的加密器
 * @date 2017-10-14 10:23
 */
class Binary_Provider : public ISecurityAlgorithm, public RefObject
{
public:
    /// 加密 
    virtual bool Encrypt(const ByteArray& data, ByteBuilder& dst)
    {
        dst += data;
        return true;
    }
    /// 解密 
    virtual bool Decrypt(const ByteArray& data, ByteBuilder& dst)
    {
        dst += data;
        return true;
    }
};
//--------------------------------------------------------- 
/**
 * @brief 自动补齐字节的加密器
 * @param [in] TProvider 需要封装的加密器类型
 * @param [in] PadSize 需要补齐的Pad块大小,例如:8,16等
 *
 * @date 2017-10-14 11:09
 */
template<class TProvider, size_t PadSize>
class Padding_Provider : public ISecurityAlgorithm, public RefObject
{
public:
    /// 返回对对象的引用
    TProvider Provider;
    /// 加密 
    virtual bool Encrypt(const ByteArray& data, ByteBuilder& dst)
    {
        const byte PAD_BYTE = 0x80;

        size_t len = 0;
        if(data.GetLength() > PadSize)
        {
            for(len = 0;len < data.GetLength();len += PadSize)
            {
                if(!Provider.Encrypt(data.SubArray(len, PadSize), dst))
                    return false;
            }
        }
        ByteBuilder tmpBuff(16);
        tmpBuff += data.SubArray(len);
        tmpBuff += PAD_BYTE;
        ByteConvert::FillN(tmpBuff, 0, PadSize, 0x00);
        return Provider.Encrypt(tmpBuff, dst);
    }
    /// 解密 
    virtual bool Decrypt(const ByteArray& data, ByteBuilder& dst)
    {
        const byte PAD_BYTE = 0x80;

        ByteArray decBuff = data.SubArray(PadSize);
        for(size_t i = 0;i < decBuff.GetLength();i += PadSize)
        {
            if(!Provider.Decrypt(decBuff.SubArray(i, PadSize), dst))
                return false;
        }
        decBuff = ByteConvert::Last(data, PadSize);
        if(!Provider.Decrypt(decBuff, dst))
            return false;
        size_t index = StringConvert::LastIndexOf(dst, PAD_BYTE);
        size_t len = dst.GetLength() - index;
        dst.RemoveTail(len);
        return true;
    }
};
//--------------------------------------------------------- 
} // namespace lc
} // namespace application 
} // namespace zhou_yb
//--------------------------------------------------------- 
#endif // _LIBZHOUYB_LC_ENCRYPTPROVIDER_H_
//========================================================= 